<template>
  <div class="mcp-service">
    <a-result
      v-if="hasError"
      status="error"
      title="页面加载失败"
      sub-title="抱歉，页面出现了一些问题"
    >
      <template #extra>
        <a-button type="primary" @click="resetError">
          重试
        </a-button>
      </template>
    </a-result>

    <template v-else>
      <a-card class="service-card">
        <template #title>
          <div class="card-title">
            <span>MCP 服务管理</span>
            <a-button type="primary" @click="showCreateService = true">
              <template #icon><plus-outlined /></template>
              创建服务
            </a-button>
          </div>
        </template>

        <!-- 搜索表单 -->
        <a-form layout="inline" class="search-form">
          <a-form-item label="关键词">
            <a-input
              v-model:value="searchValues.keyword"
              placeholder="搜索服务名称或描述"
              allow-clear
              @change="handleSearch"
            />
          </a-form-item>
          <a-form-item label="服务类型">
            <a-select
              v-model:value="searchValues.type"
              placeholder="选择服务类型"
              style="width: 120px"
              allow-clear
              @change="handleSearch"
            >
              <a-select-option value="query">查询服务</a-select-option>
              <a-select-option value="command">命令服务</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item label="状态">
            <a-select
              v-model:value="searchValues.status"
              placeholder="选择状态"
              style="width: 120px"
              allow-clear
              @change="handleSearch"
            >
              <a-select-option value="active">启用</a-select-option>
              <a-select-option value="inactive">禁用</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item>
            <a-space>
              <a-button type="primary" @click="handleSearch">
                <template #icon><search-outlined /></template>
                搜索
              </a-button>
              <a-button @click="handleReset">
                <template #icon><reload-outlined /></template>
                重置
              </a-button>
            </a-space>
          </a-form-item>
        </a-form>

        <!-- 服务列表 -->
        <a-table
          :columns="columns"
          :data-source="services"
          :loading="loading"
          :pagination="pagination"
          @change="handleTableChange"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'name'">
              <a-tooltip :title="record.description">
                {{ record.name }}
              </a-tooltip>
            </template>
            <template v-if="column.key === 'type'">
              <a-tag :color="getTypeColor(record.type)">
                {{ getTypeText(record.type) }}
              </a-tag>
            </template>
            <template v-if="column.key === 'status'">
              <a-tag :color="record.status === 'active' ? 'success' : 'error'">
                {{ record.status === 'active' ? '启用' : '禁用' }}
              </a-tag>
            </template>
            <template v-if="column.key === 'action'">
              <a-space>
                <a-button type="link" @click="handleEdit(record)">
                  <template #icon><edit-outlined /></template>
                  编辑
                </a-button>
                <a-button type="link" @click="handleTest(record)">
                  <template #icon><play-circle-outlined /></template>
                  测试
                </a-button>
                <a-popconfirm
                  title="确定要删除这个服务吗？"
                  @confirm="handleDelete(record)"
                >
                  <a-button type="link" danger>
                    <template #icon><delete-outlined /></template>
                    删除
                  </a-button>
                </a-popconfirm>
              </a-space>
            </template>
          </template>
        </a-table>
      </a-card>

      <!-- 创建/编辑服务表单 -->
      <a-modal
        v-model:visible="showCreateService"
        :title="editingService ? '编辑服务' : '创建服务'"
        @ok="handleSubmit"
        @cancel="handleCancel"
        :confirmLoading="submitting"
        :maskClosable="false"
        :keyboard="false"
      >
        <a-form
          :model="serviceForm"
          :rules="rules"
          ref="formRef"
          :label-col="{ span: 6 }"
          :wrapper-col="{ span: 16 }"
        >
          <a-form-item label="服务名称" name="name">
            <a-input v-model:value="serviceForm.name" placeholder="请输入服务名称" />
          </a-form-item>
          <a-form-item label="服务描述" name="description">
            <a-textarea
              v-model:value="serviceForm.description"
              placeholder="请输入服务描述"
              :rows="3"
            />
          </a-form-item>
          <a-form-item label="数据库连接" name="connection">
            <a-select
              v-model:value="serviceForm.connection"
              placeholder="请选择数据库连接"
            >
              <a-select-option
                v-for="conn in connections"
                :key="conn.id"
                :value="conn.id"
              >
                {{ conn.name }}
              </a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item label="SQL 查询" name="sql">
            <a-textarea
              v-model:value="serviceForm.sql"
              placeholder="请输入 SQL 查询语句"
              :rows="5"
            />
          </a-form-item>
          <a-form-item label="参数配置">
            <div v-for="(param, index) in serviceForm.parameters" :key="index" class="param-item">
              <a-row :gutter="16">
                <a-col :span="6">
                  <a-input
                    v-model:value="param.name"
                    placeholder="参数名"
                  />
                </a-col>
                <a-col :span="4">
                  <a-select
                    v-model:value="param.type"
                    placeholder="类型"
                  >
                    <a-select-option value="string">字符串</a-select-option>
                    <a-select-option value="number">数字</a-select-option>
                    <a-select-option value="boolean">布尔值</a-select-option>
                    <a-select-option value="date">日期</a-select-option>
                  </a-select>
                </a-col>
                <a-col :span="4">
                  <a-checkbox
                    v-model:checked="param.required"
                  >
                    必填
                  </a-checkbox>
                </a-col>
                <a-col :span="8">
                  <a-input
                    v-model:value="param.default"
                    placeholder="默认值"
                  />
                </a-col>
                <a-col :span="2">
                  <a-button
                    type="link"
                    danger
                    @click="removeParam(index)"
                  >
                    删除
                  </a-button>
                </a-col>
              </a-row>
            </div>
            <a-button
              type="dashed"
              block
              @click="addParam"
              style="margin-top: 8px"
            >
              <plus-outlined /> 添加参数
            </a-button>
          </a-form-item>
        </a-form>
      </a-modal>

      <!-- 测试服务对话框 -->
      <a-modal
        v-model:visible="showTestService"
        title="测试服务"
        @ok="handleTestSubmit"
        :confirmLoading="testing"
      >
        <a-form
          :model="testForm"
          :label-col="{ span: 6 }"
          :wrapper-col="{ span: 16 }"
        >
          <a-form-item
            v-for="param in testForm.parameters"
            :key="param.name"
            :label="param.name"
            :required="param.required"
          >
            <a-input
              v-if="param.type === 'string'"
              v-model:value="param.value"
              :placeholder="请输入参数值"
            />
            <a-input-number
              v-else-if="param.type === 'number'"
              v-model:value="param.value"
              :placeholder="请输入参数值"
            />
            <a-switch
              v-else-if="param.type === 'boolean'"
              v-model:checked="param.value"
            />
            <a-date-picker
              v-else-if="param.type === 'date'"
              v-model:value="param.value"
              style="width: 100%"
            />
          </a-form-item>
        </a-form>

        <!-- 测试结果 -->
        <div v-if="testResult" class="test-result">
          <a-divider>测试结果</a-divider>
          <a-alert
            :type="testResult.success ? 'success' : 'error'"
            :message="testResult.message"
            style="margin-bottom: 16px"
          />
          <a-table
            v-if="testResult.data"
            :columns="resultColumns"
            :data-source="testResult.data"
            :pagination="{ pageSize: 5 }"
          />
        </div>
      </a-modal>
    </template>
  </div>
</template>

<script setup>
import { ref, onMounted, onErrorCaptured } from 'vue'
import { message } from 'ant-design-vue'
import {
  PlusOutlined,
  SearchOutlined,
  ReloadOutlined,
  EditOutlined,
  DeleteOutlined,
  PlayCircleOutlined
} from '@ant-design/icons-vue'
import { useMCPServiceStore } from '@/stores/mcpService'
import { useDatabaseStore } from '@/stores/database'

const mcpServiceStore = useMCPServiceStore()
const databaseStore = useDatabaseStore()

// 错误处理
const error = ref(null)
const hasError = ref(false)

// 错误捕获
onErrorCaptured((err, instance, info) => {
  console.error('Component Error:', err)
  console.error('Error Info:', info)
  error.value = err
  hasError.value = true
  return false // 阻止错误继续传播
})

// 重置错误状态
const resetError = () => {
  error.value = null
  hasError.value = false
}

// 状态
const loading = ref(false)
const submitting = ref(false)
const testing = ref(false)
const showCreateService = ref(false)
const showTestService = ref(false)
const editingService = ref(null)
const services = ref([])
const connections = ref([])
const testResult = ref(null)

// 表单
const formRef = ref(null)
const serviceForm = ref({
  name: '',
  description: '',
  connection: undefined,
  sql: '',
  parameters: []
})

const testForm = ref({
  parameters: []
})

// SQL 验证函数
const validateSQL = async (rule, value) => {
  if (!value) {
    return Promise.reject('请输入 SQL 查询语句')
  }
  
  // 检查 SQL 语句是否包含参数占位符
  const params = serviceForm.value.parameters || []
  const paramNames = params.map(p => p.name)
  
  // 检查每个参数是否都在 SQL 中使用
  for (const param of params) {
    if (!value.includes(`:${param.name}`)) {
      return Promise.reject(`SQL 语句中未使用参数 "${param.name}"`)
    }
  }
  
  // 检查 SQL 中是否有未定义的参数
  const sqlParams = value.match(/:\w+/g) || []
  for (const sqlParam of sqlParams) {
    const paramName = sqlParam.substring(1)
    if (!paramNames.includes(paramName)) {
      return Promise.reject(`SQL 语句中使用了未定义的参数 "${paramName}"`)
    }
  }
  
  return Promise.resolve()
}

// 参数验证函数
const validateParameters = async (rule, value) => {
  if (!Array.isArray(value)) {
    return Promise.reject('参数配置格式错误')
  }
  
  const names = new Set()
  for (const param of value) {
    if (!param.name) {
      return Promise.reject('参数名称不能为空')
    }
    if (names.has(param.name)) {
      return Promise.reject(`参数名称 "${param.name}" 重复`)
    }
    names.add(param.name)
    
    if (!param.type) {
      return Promise.reject(`参数 "${param.name}" 的类型不能为空`)
    }
  }
  
  return Promise.resolve()
}

// 表单验证规则
const rules = {
  name: [
    { required: true, message: '请输入服务名称' },
    { max: 50, message: '服务名称不能超过50个字符' }
  ],
  description: [
    { max: 200, message: '服务描述不能超过200个字符' }
  ],
  connection: [
    { required: true, message: '请选择数据库连接' }
  ],
  sql: [
    { required: true, message: '请输入 SQL 查询语句' },
    { validator: validateSQL }
  ],
  parameters: [
    { validator: validateParameters }
  ]
}

// 搜索表单
const searchValues = ref({
  keyword: '',
  type: undefined,
  status: undefined
})

// 表格列定义
const columns = [
  {
    title: '服务名称',
    dataIndex: 'name',
    key: 'name',
    width: 200,
    ellipsis: true
  },
  {
    title: '服务类型',
    dataIndex: 'type',
    key: 'type',
    width: 120
  },
  {
    title: '数据库连接',
    dataIndex: 'connection_name',
    key: 'connection_name',
    width: 150
  },
  {
    title: '状态',
    dataIndex: 'status',
    key: 'status',
    width: 100
  },
  {
    title: '创建时间',
    dataIndex: 'created_at',
    key: 'created_at',
    width: 180
  },
  {
    title: '最后使用时间',
    dataIndex: 'last_used_at',
    key: 'last_used_at',
    width: 180
  },
  {
    title: '操作',
    key: 'action',
    fixed: 'right',
    width: 200
  }
]

// 结果表格列定义
const resultColumns = [
  {
    title: '字段',
    dataIndex: 'field',
    key: 'field'
  },
  {
    title: '值',
    dataIndex: 'value',
    key: 'value'
  }
]

// 分页配置
const pagination = ref({
  current: 1,
  pageSize: 10,
  total: 0,
  showSizeChanger: true,
  showQuickJumper: true,
  showTotal: (total) => `共 ${total} 条记录`,
  pageSizeOptions: ['10', '20', '50', '100']
})

// 获取服务类型颜色
const getTypeColor = (type) => {
  const colors = {
    query: 'blue',
    command: 'green'
  }
  return colors[type] || 'default'
}

// 获取服务类型文本
const getTypeText = (type) => {
  const texts = {
    query: '查询服务',
    command: '命令服务'
  }
  return texts[type] || type
}

// 处理搜索
const handleSearch = async () => {
  pagination.value.current = 1
  await fetchServices()
}

// 处理重置
const handleReset = async () => {
  searchValues.value = {
    keyword: '',
    type: undefined,
    status: undefined
  }
  pagination.value.current = 1
  await fetchServices()
}

// 处理表格变化
const handleTableChange = (pag) => {
  pagination.value = {
    ...pagination.value,
    current: pag.current,
    pageSize: pag.pageSize
  }
  fetchServices()
}

// 获取服务列表
const fetchServices = async () => {
  if (hasError.value) {
    resetError()
  }
  
  loading.value = true
  try {
    const { data, total } = await mcpServiceStore.fetchServices({
      page: pagination.value.current,
      pageSize: pagination.value.pageSize,
      keyword: searchValues.value.keyword,
      type: searchValues.value.type,
      status: searchValues.value.status
    })
    services.value = Array.isArray(data) ? data : []
    pagination.value.total = total || 0
  } catch (error) {
    console.error('Fetch Services Error:', error)
    message.error('获取服务列表失败')
    services.value = []
    pagination.value.total = 0
  } finally {
    loading.value = false
  }
}

// 加载数据库连接
const fetchConnections = async () => {
  if (hasError.value) {
    resetError()
  }
  
  try {
    const result = await databaseStore.getConnections()
    connections.value = result.data || []
  } catch (error) {
    console.error('Fetch Connections Error:', error)
    message.error('加载数据库连接失败')
    connections.value = []
  }
}

// 添加参数
const addParam = () => {
  serviceForm.value.parameters.push({
    name: '',
    type: 'string',
    required: false,
    default: ''
  })
}

// 删除参数
const removeParam = (index) => {
  serviceForm.value.parameters.splice(index, 1)
}

// 编辑服务
const handleEdit = (record) => {
  editingService.value = record
  serviceForm.value = { ...record }
  showCreateService.value = true
}

// 测试服务
const handleTest = (record) => {
  editingService.value = record
  testForm.value.parameters = record.parameters.map(p => ({
    ...p,
    value: p.default
  }))
  showTestService.value = true
}

// 提交测试
const handleTestSubmit = async () => {
  testing.value = true
  try {
    const params = {}
    testForm.value.parameters.forEach(p => {
      params[p.name] = p.value
    })
    
    const result = await mcpServiceStore.testService(editingService.value.id, params)
    testResult.value = {
      success: true,
      message: '测试成功',
      data: result.data
    }
  } catch (error) {
    testResult.value = {
      success: false,
      message: error.message || '测试失败'
    }
  } finally {
    testing.value = false
  }
}

// 提交表单
const handleSubmit = async () => {
  try {
    await formRef.value.validate()
    submitting.value = true

    // 处理参数默认值
    const formData = {
      ...serviceForm.value,
      parameters: serviceForm.value.parameters.map(param => ({
        ...param,
        default: param.default || null
      }))
    }

    if (editingService.value) {
      await mcpServiceStore.updateService(editingService.value.id, formData)
      message.success('更新服务成功')
    } else {
      await mcpServiceStore.createService(formData)
      message.success('创建服务成功')
    }

    showCreateService.value = false
    editingService.value = null
    serviceForm.value = {
      name: '',
      description: '',
      connection: undefined,
      sql: '',
      parameters: []
    }
    await fetchServices()
  } catch (error) {
    if (error.errorFields) {
      // 表单验证错误
      const firstError = error.errorFields[0]
      message.error(firstError.errors[0])
    } else {
      message.error(error.message || '操作失败')
    }
  } finally {
    submitting.value = false
  }
}

// 取消编辑
const handleCancel = () => {
  showCreateService.value = false
  editingService.value = null
  serviceForm.value = {
    name: '',
    description: '',
    connection: undefined,
    sql: '',
    parameters: []
  }
  formRef.value?.resetFields()
}

// 删除服务
const handleDelete = async (record) => {
  try {
    await mcpServiceStore.deleteService(record.id)
    message.success('删除服务成功')
    fetchServices()
  } catch (error) {
    message.error('删除服务失败')
  }
}

// 初始化
onMounted(async () => {
  try {
    await Promise.all([
      fetchServices(),
      fetchConnections()
    ])
  } catch (error) {
    console.error('Initialization Error:', error)
    message.error('初始化失败，请刷新页面重试')
  }
})
</script>

<style scoped>
.mcp-service {
  padding: 24px;
}

.service-card {
  margin-bottom: 24px;
}

.card-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.search-form {
  margin-bottom: 24px;
  padding: 24px;
  background: #fafafa;
  border-radius: 2px;
}

/* 暗色主题适配 */
[data-theme='dark'] .search-form {
  background: #1f1f1f;
}

/* 响应式布局 */
@media (max-width: 768px) {
  .mcp-service {
    padding: 16px;
  }

  .search-form {
    padding: 16px;
  }

  .search-form :deep(.ant-form-item) {
    margin-bottom: 16px;
  }
}

.param-item {
  margin-bottom: 8px;
}

.test-result {
  margin-top: 16px;
}
</style> 